AddCSLuaFile("cl_init.lua") 
AddCSLuaFile("shared.lua") 
include('shared.lua')

ENT.SequenceEntities = {}
ENT.SequenceActor = nil
ENT.ActorOffset = Vector(0,0,0)
ENT.IsComplete = false
ENT.HasNoAnimation = true
ENT.OnAnimation = 1

gAnimSequenceUniqueID = 1

//TODO: clean up code!!!!!!!!!!!

function ENT:Release()
	
	if self.SequenceEntities then
		for _,obj in pairs(self.SequenceEntities) do
			if obj and obj:IsValid() then
				obj:Fire("CancelSequence", "", 0)
				obj:Remove()
			end
		end
	else
		if self.HasNoAnimation == true and self.SequenceActor and self.SequenceActor:IsValid() then
			self.SequenceActor:SetSchedule(SCHED_NONE )
		end
	end
end

function ENT:Initialize() 

	self.Entity:DrawShadow(false)
	self:SetSolid(SOLID_NONE)
	self:SetName(string.format("%s_%i",self:GetClass(),gAnimSequenceUniqueID))
	gAnimSequenceUniqueID = gAnimSequenceUniqueID + 1

end

function ENT:Think()

	//This has been set true because the actor has had
	//no aniamtion sequence set for this animation_sequence
	//node. To give smooth animation we basically want to 
	//use the existing schedules system for npcs and transfer 
	//to next node when actor comes within certain distance
	if self.HasNoAnimation == true then

		if self.SequenceActor:GetPos():Distance( self:GetAnimationPosition()) < 25 then
			self:AcceptInput("AnimationEnd", nil, self.SequenceActor)
		end
	end

end

function ENT:GetAnimationPosition()
	local position = Vector(0,0,0)
	local traceRes = util.QuickTrace(self:GetPos()+ self.ActorOffset, self:GetPos() + self.ActorOffset- Vector(0,0,1000), {self, actor})
	if traceRes.HitWorld then
		position = traceRes.HitPos
	else //try the other way
		traceRes = util.QuickTrace(self:GetPos()+ self.ActorOffset, self:GetPos() + self.ActorOffset+ Vector(0,0,1000), {self, actor})
		if traceRes.HitWorld then
			position = traceRes.HitPos 
		else
			//we did our best
			position = self:GetPos()
		end
	end		
	return position
end

function ENT:ActorExecute(actor, animationSequence, transitionAnimation, actorOffset)

	self.ActorOffset = actorOffset or Vector(0,0,0)

	if animationSequence == nil or #animationSequence == 0 then

		print("REM: ",transitionAnimation )
		local scheduleType = 0
		if transitionAnimation == "Walk" then
			scheduleType = SCHED_FORCED_GO 
			print("set: " ,scheduleType)
		elseif transitionAnimation == "Run" then
			scheduleType = SCHED_FORCED_GO_RUN
			print("set: " ,scheduleType)
		else
			scheduleType = SCHED_NONE
			print("set: " ,scheduleType)
			actor:SetPos(self:GetAnimationPosition())
		end	
		actor:SetLastPosition( self:GetAnimationPosition())
		actor:SetSchedule( scheduleType )

		self.HasNoAnimation = true	
		self.SequenceActor = actor
//		
//		actor:SetSchedule( SCHED_FORCED_GO )
		self.SequenceEntities = {}
		return
	end

	self.HasNoAnimation = false
	local sequenceEnts = {}
	local i = 1

	print("Building animation sequence:")

	for kSeq, oSeq in pairs(animationSequence) do

		local scriptedSequence = ents.Create("scripted_sequence")

		scriptedSequence:SetKeyValue("m_bLoopActionSequence", "0")			
		scriptedSequence:SetKeyValue("m_iszEntity", actor:GetName())

		local targetname = string.format("anim_sequence_%i",i)
		//oSeq.Effect
		//oSeq.Target
		scriptedSequence:SetKeyValue("m_iszPlay", oSeq.Animation)
		scriptedSequence:SetPos(self:GetAnimationPosition())	//stack these sequence action vectors
		scriptedSequence:SetKeyValue("targetname",targetname)	


		//For the first animation we need to indicate that the actor
		//will use it's transition animation to get to the node
		if i == 1 then
			if transitionAnimation == "Walk" then
				scriptedSequence:SetKeyValue("m_fMoveTo", "1")
			elseif transitionAnimation == "Run" then
				scriptedSequence:SetKeyValue("m_fMoveTo", "2")
			else 
				scriptedSequence:SetKeyValue("m_fMoveTo", "4")
			end
		else
			scriptedSequence:SetKeyValue("m_fMoveTo", "1")
		end
						 
		scriptedSequence:Spawn()
		if i != #animationSequence then
			scriptedSequence:Fire("AddOutput", "OnEndSequence " .. self:GetName() .. ":SubAnimationEnd:0:0:1", 0)
		end

		sequenceEnts[i] = scriptedSequence
		i = i + 1
	end

	sequenceEnts[#animationSequence]:Fire("AddOutput", "OnEndSequence " .. self:GetName() .. ":AnimationEnd:0:0:1", 0)
	sequenceEnts[1]:Fire("BeginSequence", "", 0)	

	self.SequenceEntities = sequenceEnts

end

function ENT:AcceptInput(name, activator, caller)
	print("recieved completion event")
	if name == "SubAnimationEnd" then
		self.OnAnimation = self.OnAnimation + 1	
		self.SequenceEntities[self.OnAnimation]:Fire("BeginSequence", "", 0)
	elseif name == "AnimationEnd" then
		self.IsComplete = true	
	else
		print("Error", "Unknown entity output 'name'")
	end
end